package com.kingmed.kmss.api.internal;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.kingmed.kmss.common.annotation.IgnoreCommonResponseAdvice;
import com.kingmed.kmss.common.constant.common.InternalApiConstants;
import com.kingmed.kmss.common.dto.base.FileQueryDTO;
import com.kingmed.kmss.common.exception.BusinessException;
import com.kingmed.kmss.common.service.obs.HuaWeiYunOBSService;
import com.kingmed.kmss.common.vo.CommonResponse;
import com.kingmed.kmss.common.vo.CommonResponseHelper;
import com.obs.services.exception.ObsException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * <p>
 * 仅用于内部，给前端提供的通用型接口，因此不写在各自微服务里
 * 此类接口不涉及权限注解！如果涉及要控制权限，必须写在对应的微服务controller层，并加上权限注解
 * 强制：只能调用framework-feign里的client，不允许添加任何业务逻辑，业务逻辑必须写在facade
 * </p>
 */
@RestController
@RequestMapping("/int/obs")
@Api(tags = "华为云OBS文件管理")
@Slf4j
public class ObsApiController {
 
	@Autowired
    private HuaWeiYunOBSService huaWeiYunOBSService;

    @ApiOperation("OBS:文件上传(存储名称:路径('例如：customer/cpm/')+毫秒时间戳_文件名称)")
    @PostMapping(value = "/upload")
    public CommonResponse<?> save(@RequestParam(value = "file", required = false) MultipartFile file,
                                  @RequestParam(value = "filePath") String filePath) {
        return CommonResponseHelper.success(huaWeiYunOBSService.fileUpload(file, filePath));
    }

    @ApiOperation("OBS:文件删除")
    @PostMapping(value = "/delete")
    public CommonResponse<?> delete(@RequestBody FileQueryDTO queryQc) {
        if (StrUtil.isEmpty(queryQc.getObsFilePathAndName())) {
            return CommonResponseHelper.fail();
        }
        huaWeiYunOBSService.delete(queryQc.getObsFilePathAndName());
        return CommonResponseHelper.success();
    }

    @ApiOperation("OBS:文件批量删除")
    @PostMapping(value = "/deletebatch")
    public CommonResponse<?> deleteBatch(@RequestBody FileQueryDTO queryQc) {
        if (ArrayUtil.isEmpty(queryQc.getObsFileNames())) {
            return CommonResponseHelper.fail();
        }
        huaWeiYunOBSService.delete(queryQc.getObsFileNames());
        return CommonResponseHelper.success();
    }


    @ApiOperation("OBS:文件下载并反馈给前端")
    @PostMapping(value = "/downloadorinline")
    public CommonResponse<?> downloadOrInline(HttpServletRequest request,
                                              HttpServletResponse response,
                                              @RequestBody FileQueryDTO queryQc) {
        String obsFilePathAndName = queryQc.getObsFilePathAndName();
        if (StrUtil.isEmpty(obsFilePathAndName)) {
            return CommonResponseHelper.fail();
        }
        try {
            huaWeiYunOBSService.fileDownload(request, response, obsFilePathAndName, queryQc.getType());
            return null;
        } catch (IOException | ObsException e) {
            return CommonResponseHelper.fail();
        }
    }

    @ApiOperation("OBS:文件下载文件流")
    @PostMapping(value = "/download")
    public CommonResponse<?> download(@RequestBody FileQueryDTO queryQc) {
        String obsFilePathAndName = queryQc.getObsFilePathAndName();
        if (StrUtil.isEmpty(obsFilePathAndName)) {
            return CommonResponseHelper.fail();
        }
        return CommonResponseHelper.success(huaWeiYunOBSService.fileDownload(obsFilePathAndName));
    }

    @ApiOperation("OBS:文件批量下载并压缩成zip")
    @GetMapping(value = "/downLoadBatchToZip")
    public void downLoadBatchToZip(@PathVariable("obsFilePathAndNames") String obsFilePathAndNames, HttpServletResponse response) {
        try {
            //todo obsFilePathAndNames 内容、格式待确认
            huaWeiYunOBSService.downLoadBatchToZip(obsFilePathAndNames, response);
        }catch (Exception e) {
            throw new BusinessException("文件下载失败");
        }
    }

    @ApiOperation("OBS:文件预览")
    @GetMapping(value = "/view")
    @IgnoreCommonResponseAdvice
    public String download(HttpServletResponse response, @RequestParam String url) {
        InputStream fis = huaWeiYunOBSService.fileDownload(url);
        try {
            OutputStream out = response.getOutputStream();
            byte[] bs = new byte[1024];
            while ((fis.read(bs) != -1)) {
                out.write(bs);
            }
            out.flush();
            out.close();
            fis.close();
        } catch (Exception e) {
            log.info("OBS:文件预览异常 = {}", e.getMessage());
        }
        return null;
    }

    @ApiOperation("OBS:文件预览Ex")
    @GetMapping(value = "/file/**")
    @IgnoreCommonResponseAdvice
    public String downloadEx(HttpServletResponse response, HttpServletRequest request) {
        String fileUrl = request.getServletPath();
        if (StringUtils.isEmpty(fileUrl)) {
            return null;
        }

        fileUrl = fileUrl.replace(InternalApiConstants.INT_OBS_FILE_PATH, "");
        InputStream fis = huaWeiYunOBSService.fileDownload(fileUrl);
        try {
            byte[] b = new byte[1024];
            OutputStream bos = response.getOutputStream();
            int len;
            while ((len = fis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            bos.close();
            fis.close();
        } catch (Exception e) {
            log.info("OBS:文件预览异常 = {}", e.getMessage());
        }
        return null;
    }
}
